package com.liuwei.spring.cloud.framework.db.mapper;/**
 * @author : BaseMapper
 * @version V1.0
 * @date: 2023/5/10 5:56 下午
 * @Description: TODO
 */

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.liuwei.spring.cloud.framework.db.entity.BaseOptimisticLockerDeleteVersionEntity;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.util.Assert;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author : BaseMapper
 * @version V1.0
 * @date: 2023/5/10 5:56 下午
 * @Description: TODO
 */
public interface BaseOptimisticLockerDeleteVersionMapper<T extends BaseOptimisticLockerDeleteVersionEntity> extends BaseMapper<T> {

    /**
     * 乐观锁支持 update 批量更新
     * @param entity 更新值
     * @param updateWrapper 查询条件
     * @return 影响行数
     *
     * updateById 支持乐观锁需先取出当前 version;  set version = newVersion where version = oldVersion;
     * 对于 new entity() 则更新失败
     */
    /*@Override
    default int update(T entity, Wrapper<T> updateWrapper){
        List<T> records = selectList(updateWrapper);
        if(CollectionUtils.isEmpty(records)){
            return 0;
        }
        CollectionUtils.emptyIfNull(records).forEach(x->{
            String id = x.getId();
            x.setId(id);
            Validators.isTrue(updateById(x)>0, StrUtil.format("Id:{} 乐观锁并发,更新失败"));
        });
        return CollectionUtils.emptyIfNull(records).size();
    }*/

    /**
     * Service 对应方法 removeById
     * @param id 主键
     * @return 变更行数
     */
    @Override
    default int deleteById(Serializable id){
        if(ObjectUtils.isEmpty(id)){
            return 0;
        }
        // 可重复读: 多次读取的 version 版本号一致
        // 记录不存在的情况 = 删除成功
        T entity = selectById(id);
        if(entity == null){
            return 1;
        }
        entity.setId(entity.getId());
        entity.setDeleted(true);
        entity.setDeletedVersion(entity.getId());
        /*
        BaseMapper update 2 种实现方法
        int updateById(@Param("et") T entity);
        int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);
        */
        return updateById(entity);
    }

    @Override
    default int deleteById(T entity) {
        String id = entity.getId();
        return deleteById(id);
    }

    /**
     * Service 对应方法 removeByMap
     * @param columnMap 查询条件
     * @return 变更行数
     */
    @Override
    default int deleteByMap(Map<String, Object> columnMap){
        List<T> records = selectByMap(columnMap);
        List<String> ids = CollectionUtils.emptyIfNull(records).stream().map(x->x.getId()).collect(Collectors.toList());
        return deleteBatchIds(ids);
    }

    /**
     * Service 对应方法 remove
     * @param queryWrapper 查询条件
     * @return 变更行数
     */
    @Override
    default int delete(Wrapper<T> queryWrapper){
        List<T> records = selectList(queryWrapper);
        List<String> ids = CollectionUtils.emptyIfNull(records).stream().map(x->x.getId()).collect(Collectors.toList());
        return deleteBatchIds(ids);
    }

    /**
     * Service 对应方法 removeByIds
     * delete from table where id in ()
     * 批量无法处理 version 和 deleted_time 的问题, 切换为单行删除(可能存在性能问题)
     * @param ids 主键
     * @return 变更行数
     */
    @Override
    default int deleteBatchIds(Collection<?> ids){
        if(CollectionUtils.isEmpty(ids)){
            return 0;
        }else{
            CollectionUtils.emptyIfNull(ids).forEach(x->{
                Assert.isTrue(deleteById(x.toString())>0, StrUtil.format("Id:{} 乐观锁并发,删除失败"));
            });
            return CollectionUtils.emptyIfNull(ids).size();
        }
    }
}
